package com.hero.content.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hero.content.mapper.CourseBaseMapper;
import com.hero.content.mapper.CourseCategoryMapper;
import com.hero.content.mapper.CourseMarketMapper;
import com.hero.content.mapper.TeachplanMapper;
import com.hero.content.model.dto.AddCourseDto;
import com.hero.content.model.dto.CourseBaseInfoDto;
import com.hero.content.model.dto.EditCourseDto;
import com.hero.content.model.dto.QueryCourseParamsDto;
import com.hero.content.model.pojo.CourseBase;
import com.hero.content.model.pojo.CourseMarket;
import com.hero.content.model.pojo.Teachplan;
import com.hero.content.model.vo.CoureseListVO;
import com.hero.content.service.CourseBaseService;
import com.hero.content.service.CourseMarketService;
import com.hero.execption.XueChengPlusException;
import com.hero.content.model.PageParams;
import com.hero.content.model.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Resource
    private CourseBaseMapper courseBaseMapper;
    @Resource
    private CourseMarketMapper marketMapper;
    @Resource
    private TeachplanMapper teachplanMapper;

    @Resource
    private CourseCategoryMapper categoryMapper;

    @Autowired
    private CourseMarketService marketService;

    /**
     * 根据条件分页查询课程列表
     *
     * @param pageParams
     * @param paramsDto
     * @return
     */
    @Override
    public PageResult<CoureseListVO> selectCourseListByPage(PageParams pageParams, QueryCourseParamsDto paramsDto) {
        // 校验分页参数
        pageParams.checkParam();
        // 写SQL语句
        Page<CourseBase> basePage = courseBaseMapper.selectPage(new Page<>(pageParams.getPageNo(), pageParams.getPageSize()),
                Wrappers.lambdaQuery(CourseBase.class)
                        .like(StrUtil.isNotEmpty(paramsDto.getCourseName()), CourseBase::getName, paramsDto.getCourseName())
                        .eq(StrUtil.isNotEmpty(paramsDto.getAuditStatus()), CourseBase::getAuditStatus, paramsDto.getAuditStatus())
                        .eq(StrUtil.isNotEmpty(paramsDto.getPublishStatus()), CourseBase::getStatus, paramsDto.getPublishStatus())
        );

        List<CoureseListVO> vos = new ArrayList<>();
        for (CourseBase course : basePage.getRecords()) {
            CoureseListVO vo = new CoureseListVO();
            BeanUtil.copyProperties(course, vo, true);

            // 查询每个课程是否需要付费
            CourseMarket market = marketMapper.selectById(course.getId());
            vo.setCharge(ObjUtil.isNotEmpty(market) ? market.getCharge() : "");
            // 查询每个课程的任务数
            List<Teachplan> teachplans = teachplanMapper.selectList(Wrappers.lambdaQuery(Teachplan.class)
                    .eq(Teachplan::getCourseId, course.getId())
                    .ne(Teachplan::getParentid, 0)
            );
            vo.setSubsectionNum(ObjUtil.isNotEmpty(teachplans) ? teachplans.size() : 0);
            vos.add(vo);
        }

        return new PageResult<>(vos, basePage.getTotal(), pageParams.getPageNo(), pageParams.getPageSize());
    }

    /**
     * 添加课程
     *
     * @param companyId 机构ID
     * @param courseDto 新增课程的表单数据
     * @return
     */
    @Transactional
    @Override
    public CourseBaseInfoDto addCourse(Long companyId, AddCourseDto courseDto) {
        // 参数校验
        // 非空   唯一   格式
        // 课程名称
        if (StrUtil.isEmpty(courseDto.getName())) throw new XueChengPlusException("课程名称为空");
        // 课程分类
        if (StrUtil.isEmpty(courseDto.getMt()) || StrUtil.isEmpty(courseDto.getSt()))
            throw new XueChengPlusException("课程分类为空");
        // 课程等级
        if (StrUtil.isEmpty(courseDto.getGrade())) throw new XueChengPlusException("课程等级为空");
        // 适用人群
        if (StrUtil.isEmpty(courseDto.getUsers())) throw new XueChengPlusException("适用人群为空");
        // 课程类型 收费模式
        if (StrUtil.isEmpty(courseDto.getCharge())) throw new XueChengPlusException("收费模式为空");


        // 拼凑一个基础课程POJO
        CourseBase courseBase = new CourseBase();
        BeanUtil.copyProperties(courseDto, courseBase, true);
        // 设置其他属性
        companyId = 1232141425L;
        courseBase.setCompanyId(companyId);
        courseBase.setCompanyName("");
        courseBase.setCreateDate(LocalDateTime.now());
        courseBase.setChangeDate(LocalDateTime.now());
        courseBase.setAuditStatus("202002");//  审核状态
        courseBase.setStatus("203001");
        courseBaseMapper.insert(courseBase);


        // 拼凑一个课程收费POJO
        CourseMarket market = new CourseMarket();
        market.setId(courseBase.getId());
        BeanUtil.copyProperties(courseDto, market, true);

        if ("201001".equals(courseDto.getCharge()) && ObjUtil.isNull(market.getPrice()))
            throw new XueChengPlusException("收费课程价格不能为空");

        marketMapper.insert(market);

        CourseBaseInfoDto infoDto = new CourseBaseInfoDto();
        BeanUtil.copyProperties(market, infoDto, true);
        infoDto.setStName(categoryMapper.selectById(courseBase.getSt()).getName());
        infoDto.setMtName(categoryMapper.selectById(courseBase.getMt()).getName());
        return infoDto;
    }

    /**
     * 根据课程id查询课程
     *
     * @param courseId
     * @return
     */
    @Override
    public CourseBaseInfoDto getCourseBaseInfo(Long courseId) {
        // 查询课程基本信息
        CourseBase courseBase = courseBaseMapper.selectById(courseId);
        // 查询课程费用
        CourseMarket courseMarket = marketMapper.selectOne(Wrappers.lambdaQuery(CourseMarket.class)
                .eq(CourseMarket::getId, courseId));
        if (!ObjUtil.isAllNotEmpty(courseBase, courseMarket)) return null;
        // 封装返回对象
        CourseBaseInfoDto courseBaseInfoDto = new CourseBaseInfoDto();
        BeanUtils.copyProperties(courseBase, courseBaseInfoDto);
        BeanUtils.copyProperties(courseMarket, courseBaseInfoDto);

        courseBaseInfoDto.setMtName(categoryMapper.selectById(courseBase.getMt()).getName());
        courseBaseInfoDto.setStName(categoryMapper.selectById(courseBase.getSt()).getName());

        courseBaseInfoDto.setPrice(courseMarket.getPrice());
        courseBaseInfoDto.setCharge(courseMarket.getCharge());

        return courseBaseInfoDto;
    }

    /**
     * 修改课程信息
     *
     * @param companyId
     * @param dto
     * @return
     */
    @Transactional
    @Override
    public CourseBaseInfoDto updateCourseBase(Long companyId, EditCourseDto dto) {
        //业务规则校验，本机构只允许修改本机构的课程
        CourseBase courseBase_u = courseBaseMapper.selectById(dto.getId());
        if (ObjUtil.isNull(courseBase_u)) {
            XueChengPlusException.cast("课程信息不存在");
        }
        if (!companyId.equals(courseBase_u.getCompanyId())) {
            XueChengPlusException.cast("本机构只允许修改本机构的课程");
        }

        //封装数据
        //将请求参数拷贝到待修改对象中
        BeanUtils.copyProperties(dto, courseBase_u);
        courseBase_u.setChangeDate(LocalDateTime.now());
        //更新到数据库
        courseBaseMapper.updateById(courseBase_u);

        //查询课程营销信息
        CourseMarket courseMarket = marketMapper.selectById(dto.getId());
        if (ObjUtil.isNull(courseMarket)) {
            courseMarket = new CourseMarket();
        }

        //判断是否收费
        String charge = dto.getCharge();
        if (charge.equals("201001")) {
            BigDecimal price = dto.getPrice();
            if (price == null || price.floatValue() <= 0) {
                XueChengPlusException.cast("课程设置了收费价格不能为空且必须大于0");
            }
        }

        //将dto中的课程营销信息拷贝至courseMarket对象中
        BeanUtils.copyProperties(dto, courseMarket);
        marketService.saveOrUpdate(courseMarket);

        return getCourseBaseInfo(dto.getId());
    }
}
